'use strict';

var DepositeContent = function(text) {
    if (text) {
        var o = JSON.parse(text);
        this.balance = new BigNumber(o.balance);
        this.expiryHeight = new BigNumber(o.expiryHeight);
    } else {
        this.balance = new BigNumber(0);
        this.expiryHeight = new BigNumber(0);
    }
};

DepositeContent.prototype = {
    toString: function() {
        return JSON.stringify(this);
    }
};

var BankVaultContract = function() {
    LocalContractStorage.defineMapProperty(this, 'bankVault', {
        parse: function(text) {
            return new DepositeContent(text);
        },
        stringify: function(o) {
            return o.toString();
        }
    });
};

// save value to contract, only after height of block, users can takeout
BankVaultContract.prototype = {
    init: function() {
        //TODO:
    },

    save: function(height) {
        var from = Blockchain.transaction.from;
        var value = Blockchain.transaction.value;
        var bk_height = new BigNumber(Blockchain.block.height);

        var orig_deposit = this.bankVault.get(from);
        if (orig_deposit) {
            value = value.plus(orig_deposit.balance);
        }

        var deposit = new DepositeContent();
        deposit.balance = value;
        deposit.expiryHeight = bk_height.plus(height);

        this.bankVault.put(from, deposit);
    },

    takeout: function(value) {
        var from = Blockchain.transaction.from;
        var bk_height = new BigNumber(Blockchain.block.height);
        var amount = new BigNumber(value);

        var deposit = this.bankVault.get(from);
        if (!deposit) {
            throw new Error('No deposit before.');
        }

        if (bk_height.lt(deposit.expiryHeight)) {
            throw new Error('Can not takeout before expiryHeight.');
        }

        if (amount.gt(deposit.balance)) {
            throw new Error('Insufficient balance.');
        }

        var result = Blockchain.transfer(from, amount);
        if (!result) {
            throw new Error('transfer failed.');
        }
        Event.Trigger('BankVault', {
            Transfer: {
                from: Blockchain.transaction.to,
                to: from,
                value: amount.toString()
            }
        });

        deposit.balance = deposit.balance.sub(amount);
        this.bankVault.put(from, deposit);
    },
    balanceOf: function() {
        var from = Blockchain.transaction.from;
        return this.bankVault.get(from);
    },
    verifyAddress: function(address) {
        // 1-valid, 0-invalid
        var result = Blockchain.verifyAddress(address);
        return {
            valid: result == 0 ? false : true
        };
    }
};
module.exports = BankVaultContract;

('use strict');

var DictItem = function(text) {
    if (text) {
        var obj = JSON.parse(text);
        this.key = obj.key;
        this.value = obj.value;
        this.author = obj.author;
    } else {
        this.key = '';
        this.author = '';
        this.value = '';
    }
};

DictItem.prototype = {
    toString: function() {
        return JSON.stringify(this);
    }
};

var SuperDictionary = function() {
    LocalContractStorage.defineMapProperty(this, 'repo', {
        parse: function(text) {
            return new DictItem(text);
        },
        stringify: function(o) {
            return o.toString();
        }
    });
};

SuperDictionary.prototype = {
    init: function() {
        // todo
    },

    save: function(key, value) {
        key = key.trim();
        value = value.trim();
        if (key === '' || value === '') {
            throw new Error('empty key / value');
        }
        if (value.length > 64 || key.length > 64) {
            throw new Error('key / value exceed limit length');
        }

        var from = Blockchain.transaction.from;
        var dictItem = this.repo.get(key);
        if (dictItem) {
            throw new Error('value has been occupied');
        }

        dictItem = new DictItem();
        dictItem.author = from;
        dictItem.key = key;
        dictItem.value = value;

        this.repo.put(key, dictItem);
    },

    get: function(key) {
        key = key.trim();
        if (key === '') {
            throw new Error('empty key');
        }
        return this.repo.get(key);
    }
};
module.exports = SuperDictionary;

Sample.prototype = {
    init: function() {
        this.size = 0;
    },
    set: function(key, value) {
        var index = this.size;
        this.arrayMap.set(index, key);
        this.dataMap.set(key, value);
        this.size += 1;
    },
    get: function(key) {
        return this.dataMap.get(key);
    },
    len: function() {
        return this.size;
    },
    forEach: function(limit, offset) {
        limit = parseInt(limit);
        offset = parseInt(offset);
        if (offset > this.size) {
            throw new Error('offset is not valid');
        }
        var number = offset + limit;
        if (number > this.size) {
            number = this.size;
        }
        var result = '';
        for (var i = offset; i < number; i++) {
            var key = this.arrayMap.get(i);
            var object = this.dataMap.get(key);
            result += 'index:' + i + ' key:' + key + ' value:' + object + '_';
        }
        return result;
    }
};

// 获得当前绑定的钱包地址
window.addEventListener('message', function(e) {
    if (e.data && e.data.data) {
        console.log('e.data.data:', e.data.data);
        if (e.data.data.account) {
            app.walletAddr = e.data.data.account;
            app.updateUserInfo();
        }
    }
});
window.postMessage(
    {
        target: 'contentscript',
        data: {},
        method: 'getAccount'
    },
    '*'
);
